// utils/util.js
/**
 * 工具函数模块
 */
const util = {
  /**
   * 默认设置配置
   */
  defaultSettings: {
    payDate: 1,
    monthlySalary: 0,
    yearlyBonus: 0,
    includeWeekends: false,
    // 五险一金设置
    insurance: {
      enabled: false,
      base: 0,
      items: {
        pension: { name: '养老保险', companyRate: 16, personalRate: 8, enabled: true },
        medical: { name: '医疗保险', companyRate: 8, personalRate: 2, enabled: true },
        unemployment: { name: '失业保险', companyRate: 0.7, personalRate: 0.3, enabled: true },
        injury: { name: '工伤保险', companyRate: 0.5, personalRate: 0, enabled: true },
        maternity: { name: '生育保险', companyRate: 0.8, personalRate: 0, enabled: true },
        housingFund: { name: '住房公积金', companyRate: 12, personalRate: 12, enabled: true }
      }
    }
  },

  /**
   * 获取存储的设置
   * @returns {Object} 设置对象
   */
  getStoredSettings: function () {
    try {
      const settings = wx.getStorageSync('cowHorseClockSettings')
      let parsedSettings
      
      // 如果settings是对象，直接返回；如果是字符串，尝试解析
      if (typeof settings === 'object' && settings !== null) {
        parsedSettings = settings
      } else if (typeof settings === 'string') {
        parsedSettings = JSON.parse(settings)
      } else {
        return { ...this.defaultSettings }
      }
      
      // 兼容性处理：确保新增字段存在
      if (!parsedSettings.insurance) {
        parsedSettings.insurance = { ...this.defaultSettings.insurance }
      }
      
      return parsedSettings
    } catch (error) {
      console.error('获取设置失败:', error)
      return { ...this.defaultSettings }
    }
  },

  /**
   * 保存设置到本地存储
   * @param {Object} settings - 要保存的设置对象
   * @returns {boolean} 保存是否成功
   */
  saveSettings: function (settings) {
    try {
      wx.setStorageSync('cowHorseClockSettings', JSON.stringify(settings))
      return true
    } catch (error) {
      console.error('保存设置失败:', error)
      throw error
    }
  },

  /**
   * 计算工作日数量
   * @param {Date} startDate - 开始日期
   * @param {Date} endDate - 结束日期
   * @param {boolean} includeWeekends - 是否包含周末
   * @returns {number} 工作日数量
   */
  calculateWorkdays: function (startDate, endDate, includeWeekends) {
    let workdays = 0
    const currentDate = new Date(startDate)
    
    // 将时间设置为工作日开始时间
    currentDate.setHours(8, 0, 0, 0)
    
    while (currentDate <= endDate) {
      // 如果包含周末，则每天都计算；否则只计算工作日
      if (includeWeekends) {
        workdays++
      } else {
        const dayOfWeek = currentDate.getDay()
        // 0是周日，6是周六
        if (dayOfWeek !== 0 && dayOfWeek !== 6) {
          workdays++
        }
      }
      
      // 移动到下一天
      currentDate.setDate(currentDate.getDate() + 1)
    }
    
    return workdays
  },

  /**
   * 获取当前工资周期的开始和结束日期
   * @param {number} payDate - 发薪日（1-31）
   * @returns {Object} 包含startDate和endDate的对象
   */
  getCurrentPayPeriod: function (payDate) {
    const today = new Date()
    const year = today.getFullYear()
    const month = today.getMonth()
    
    // 发薪日的日期对象
    let payDateObj = new Date(year, month, payDate)
    
    // 如果今天的日期已经过了发薪日，则发薪日应该是下个月
    if (today.getDate() > payDate) {
      payDateObj = new Date(year, month + 1, payDate)
    }
    
    // 结束日期是发薪日当天
    const endDate = new Date(payDateObj)
    endDate.setHours(18, 0, 0, 0)
    
    // 开始日期是上一个发薪日的第二天
    const startDate = new Date(payDateObj)
    startDate.setMonth(startDate.getMonth() - 1)
    startDate.setDate(startDate.getDate() + 1)
    startDate.setHours(8, 0, 0, 0)
    
    return { startDate, endDate }
  },

  /**
   * 计算工资信息
   * @returns {Object} 包含所有工资信息的对象
   */
  calculateSalaryInfo: function () {
    const settings = this.getStoredSettings()
    const { payDate, monthlySalary, yearlyBonus, includeWeekends, insurance } = settings
    
    // 获取当前时间
    const now = new Date()
    const today = new Date(now.getFullYear(), now.getMonth(), now.getDate())
    
    // 计算工资周期和本月工作日
    const { startDate, endDate } = this.getCurrentPayPeriod(payDate)
    const { monthTotalWorkdays, monthWorkedDays } = this.calculateMonthWorkdays(today, includeWeekends)
    
    // 计算基本工资信息
    const { dailyWage, todaySalary, monthlySalaryEarned } = this.calculateBasicWages(
      today, monthTotalWorkdays, monthWorkedDays, monthlySalary, includeWeekends
    )
    
    // 计算年终奖信息
    const { todayBonus } = this.calculateBonusInfo(today, yearlyBonus, includeWeekends)
    
    // 计算五险一金信息
    const { insuranceInfo, afterTaxDailyWage, afterTaxMonthlySalary } = this.calculateInsuranceInfo(
      insurance, dailyWage, today, monthTotalWorkdays, monthWorkedDays, includeWeekends
    )
    
    // 计算最终工资信息
    const finalTodaySalary = this.calculateFinalTodaySalary(
      insuranceInfo, todaySalary, todayBonus, afterTaxDailyWage, today, includeWeekends, monthWorkedDays
    )
    
    const finalMonthlySalaryEarned = this.calculateFinalMonthlySalary(
      insuranceInfo, monthlySalaryEarned, afterTaxDailyWage, today, includeWeekends, monthWorkedDays
    )
    
    // 计算年薪
    const yearlySalary = monthlySalary * 12 + yearlyBonus
    
    // 输出调试信息
    this.logSalaryCalculationDebug({
      today, now, monthTotalWorkdays, monthWorkedDays, dailyWage, afterTaxDailyWage,
      todaySalary: finalTodaySalary, todayBonus, monthlySalaryEarned: finalMonthlySalaryEarned,
      includeWeekends, insurance: insuranceInfo
    })
    
    return {
      monthlySalary,
      dailyWage,
      afterTaxDailyWage,
      todaySalary: finalTodaySalary,
      monthlySalaryEarned: finalMonthlySalaryEarned,
      totalSalary: monthlySalary,
      afterTaxMonthlySalary,
      payDate,
      yearlyBonus,
      yearlySalary,
      todayBonus,
      insurance: insuranceInfo
    }
  },

  /**
   * 计算本月工作日信息
   */
  calculateMonthWorkdays: function (today, includeWeekends) {
    const monthStart = new Date(today.getFullYear(), today.getMonth(), 1)
    const monthEnd = new Date(today.getFullYear(), today.getMonth() + 1, 0)
    
    const monthTotalWorkdays = this.calculateWorkdays(monthStart, monthEnd, includeWeekends)
    const monthWorkedDays = this.calculateWorkdays(monthStart, today, includeWeekends)
    
    return { monthTotalWorkdays, monthWorkedDays }
  },

  /**
   * 计算基本工资信息
   */
  calculateBasicWages: function (today, monthTotalWorkdays, monthWorkedDays, monthlySalary, includeWeekends) {
    const dailyWage = monthTotalWorkdays > 0 ? monthlySalary / monthTotalWorkdays : 0
    const todaySalary = this.calculateTodaySalary(today, dailyWage, includeWeekends)
    
    const previousDaysEarned = (monthWorkedDays - (todaySalary > 0 ? 1 : 0)) * dailyWage
    const monthlySalaryEarned = previousDaysEarned + todaySalary
    
    return { dailyWage, todaySalary, monthlySalaryEarned }
  },

  /**
   * 计算年终奖信息
   */
  calculateBonusInfo: function (today, yearlyBonus, includeWeekends) {
    const yearWorkdays = this.calculateWorkdays(
      new Date(today.getFullYear(), 0, 1),
      new Date(today.getFullYear(), 11, 31),
      includeWeekends
    )
    
    const dailyBonus = yearWorkdays > 0 ? yearlyBonus / yearWorkdays : 0
    const todayBonus = this.calculateTodaySalary(today, dailyBonus, includeWeekends)
    
    return { todayBonus }
  },

  /**
   * 计算五险一金信息
   */
  calculateInsuranceInfo: function (insurance, dailyWage, today, monthTotalWorkdays, monthWorkedDays, includeWeekends) {
    let insuranceInfo = null
    let afterTaxDailyWage = dailyWage
    let afterTaxMonthlySalary = 0
    
    if (insurance.enabled && insurance.base > 0) {
      insuranceInfo = this.calculateInsurance(insurance.base, insurance.items)
      const monthlyDeduction = insuranceInfo.total.personal
      afterTaxDailyWage = monthTotalWorkdays > 0 ? (dailyWage * monthTotalWorkdays - monthlyDeduction) / monthTotalWorkdays : 0
      afterTaxMonthlySalary = dailyWage * monthTotalWorkdays - monthlyDeduction
    }
    
    return { insuranceInfo, afterTaxDailyWage, afterTaxMonthlySalary }
  },

  /**
   * 计算最终今日工资
   */
  calculateFinalTodaySalary: function (insuranceInfo, todaySalary, todayBonus, afterTaxDailyWage, today, includeWeekends, monthWorkedDays) {
    if (insuranceInfo) {
      const todaySalaryAfterTax = this.calculateTodaySalary(today, afterTaxDailyWage, includeWeekends)
      return todaySalaryAfterTax + todayBonus
    }
    return todaySalary + todayBonus
  },

  /**
   * 计算最终本月工资
   */
  calculateFinalMonthlySalary: function (insuranceInfo, monthlySalaryEarned, afterTaxDailyWage, today, includeWeekends, monthWorkedDays) {
    if (insuranceInfo) {
      const todaySalaryAfterTax = this.calculateTodaySalary(today, afterTaxDailyWage, includeWeekends)
      const previousDaysEarnedAfterTax = (monthWorkedDays - (todaySalaryAfterTax > 0 ? 1 : 0)) * afterTaxDailyWage
      return previousDaysEarnedAfterTax + todaySalaryAfterTax
    }
    return monthlySalaryEarned
  },

  /**
   * 输出工资计算调试信息
   */
  logSalaryCalculationDebug: function (debugInfo) {
    console.log('工资计算调试信息:', {
      today: debugInfo.today.toLocaleDateString(),
      now: debugInfo.now.toLocaleTimeString(),
      monthTotalWorkdays: debugInfo.monthTotalWorkdays,
      monthWorkedDays: debugInfo.monthWorkedDays,
      dailyWage: debugInfo.dailyWage,
      afterTaxDailyWage: debugInfo.afterTaxDailyWage,
      todaySalary: debugInfo.todaySalary,
      todayBonus: debugInfo.todayBonus,
      monthlySalaryEarned: debugInfo.monthlySalaryEarned,
      includeWeekends: debugInfo.includeWeekends,
      insurance: debugInfo.insurance
    })
  },

  /**
   * 计算五险一金
   * @param {number} base - 缴纳基数
   * @param {Object} items - 保险项目配置
   * @returns {Object} 五险一金计算结果
   */
  calculateInsurance: function (base, items) {
    const result = {
      base: base,
      items: {},
      total: {
        company: 0,
        personal: 0,
        overall: 0
      }
    }
    
    // 计算各项保险费用
    for (const [key, item] of Object.entries(items)) {
      if (!item.enabled) continue
      
      const companyAmount = base * item.companyRate / 100
      const personalAmount = base * item.personalRate / 100
      
      result.items[key] = {
        name: item.name,
        base: base,
        companyRate: item.companyRate,
        personalRate: item.personalRate,
        companyAmount: companyAmount,
        personalAmount: personalAmount,
        totalAmount: companyAmount + personalAmount
      }
      
      // 累计总费用
      result.total.company += companyAmount
      result.total.personal += personalAmount
      result.total.overall += companyAmount + personalAmount
    }
    
    return result
  },

  /**
   * 计算今日已得工资（按时间比例）
   * @param {Date} today - 今天的日期
   * @param {number} dailyWage - 日薪
   * @param {boolean} includeWeekends - 是否包含周末
   * @returns {number} 今日已得工资
   */
  calculateTodaySalary: function (today, dailyWage, includeWeekends) {
    // 检查今天是否是工作日
    if (!includeWeekends) {
      const dayOfWeek = today.getDay()
      if (dayOfWeek === 0 || dayOfWeek === 6) {
        return 0
      }
    }
    
    // 获取当前时间
    const now = new Date()
    const workStart = new Date(today.getFullYear(), today.getMonth(), today.getDate(), 8, 0, 0)
    const workEnd = new Date(today.getFullYear(), today.getMonth(), today.getDate(), 18, 0, 0)
    
    // 如果当前时间在工作开始前，返回0
    if (now < workStart) {
      return 0
    }
    
    // 如果当前时间在工作结束后，返回全天工资
    if (now >= workEnd) {
      return dailyWage
    }
    
    // 计算工作时间比例
    const totalWorkMinutes = 10 * 60 // 10小时工作时间
    const workedMinutes = (now - workStart) / (1000 * 60)
    const workRatio = Math.max(0, Math.min(1, workedMinutes / totalWorkMinutes))
    
    return dailyWage * workRatio
  },

  /**
   * 格式化金额显示
   * @param {number} amount - 金额数值
   * @returns {string} 格式化后的金额字符串
   */
  formatCurrency: function (amount) {
    return `¥${amount.toFixed(2)}`
  },

  /**
   * 显示提示信息
   * @param {string} message - 提示内容
   * @param {string} type - 提示类型 ('success' | 'error')
   */
  showToast: function (message, type = 'success') {
    wx.showToast({
      title: message,
      icon: type === 'success' ? 'success' : 'none',
      duration: 2000,
      mask: true
    })
  },

  /**
   * 显示加载提示
   * @param {string} title - 加载提示文字
   */
  showLoading: function (title = '加载中...') {
    wx.showLoading({
      title: title,
      mask: true
    })
  },

  /**
   * 隐藏加载提示
   */
  hideLoading: function () {
    wx.hideLoading()
  },

  /**
   * 显示模态对话框
   * @param {Object} options - 对话框配置
   * @returns {Promise<boolean>} 用户是否确认
   */
  showModal: function (options) {
    return new Promise((resolve, reject) => {
      wx.showModal({
        title: options.title || '提示',
        content: options.content || '',
        showCancel: options.showCancel !== false,
        cancelText: options.cancelText || '取消',
        confirmText: options.confirmText || '确定',
        confirmColor: options.confirmColor || '#007aff',
        success: (res) => {
          if (res.confirm) {
            resolve(true)
          } else {
            resolve(false)
          }
        },
        fail: (error) => {
          reject(error)
        }
      })
    })
  }
}

module.exports = util